﻿using System;
using System.Xml.Serialization;

[XmlRootAttribute("tv")]
public class TVListing 
{   
	public TVListing()
	{
		Channels = new Channel[0];
		Programs = new Program[0];
	}

	[XmlElementAttribute("channel")]
	public Channel[] Channels;
	
	[XmlElementAttribute("programme")]
	public Program[] Programs;
	
	[XmlAttributeAttribute("date")]
	public string DateString;
	[XmlIgnore]
	public DateTime Date
	{
		get
		{
			if (DateString == null || DateString.Length == 0)
				return DateTime.MinValue;
			return DateTime.ParseExact(DateString, "yyyyMMdd", null);
		}
		set
		{
			DateString = value.ToString("yyyyMMdd");
		}
	}
	
	[XmlAttributeAttribute("source-info-url")]
	public string SourceURL;
	
	[XmlAttributeAttribute("source-info-name")]
	public string SourceName;
	
	[XmlAttributeAttribute("source-data-url")]
	public string SourceDataURL;
	
	[XmlAttributeAttribute("generator-info-name")]
	public string GeneratorName;
	
	[XmlAttributeAttribute("generator-info-url")]
	public string GeneratorURL;
}

public class Channel : IComparable
{
	public Channel()
	{
		DisplayNames = new Descriptor[0];
		Icons = new Icon[0];
		URLs = new string[0];
	}

	[XmlElementAttribute("display-name")]
	public Descriptor[] DisplayNames;
	[XmlIgnore]
	public int ChannelNumber
	{
		get
		{
			double Number = 0;
			if (DisplayNames != null)
				foreach (Descriptor d in DisplayNames)
					if (Double.TryParse(d.Value, System.Globalization.NumberStyles.Integer , null, out Number))
						break;
			return (int)Number;
		}
	}
	
	[XmlElementAttribute("icon")]
	public Icon[] Icons;
	
	[XmlElementAttribute("url")]
	public string[] URLs;
	
	[XmlAttributeAttribute("id")]
	public string ID;

	public int CompareTo(object obj)
	{
		if (obj.GetType() != typeof (Channel))
			throw new ArgumentException("object is not a Channel");
		Channel that = (Channel)obj;
		return this.ChannelNumber.CompareTo(that.ChannelNumber);
	}

	public override string ToString()
	{
		if (DisplayNames != null && DisplayNames.Length > 0)
			return DisplayNames[0].Value;
		return ID;
	}

}

public class Icon 
{  
	public Icon()
	{
		Width = Height = 0;
	}

	[XmlAttributeAttribute("src")]
	public string Source;
	
	[XmlAttributeAttribute("width")]
	public int Width;
	
	[XmlAttributeAttribute("height")]
	public int Height;
}

public class Program : IComparable
{
	public Program()
	{
		Title = new Descriptor[0];
		Subtitle = new Descriptor[0];
		Description = new Descriptor[0];
		Category = new Descriptor[0];
		Icon = new Icon[0];
		URLs = new string[0];
		Country = new Descriptor[0];
		Subtitles = new Subtitle[0];
		Ratings = new Rating[0];
		LengthField = new Length();
	}

	[XmlElementAttribute("title")]
	public Descriptor[] Title;
	
	[XmlElementAttribute("sub-title")]
	public Descriptor[] Subtitle;
	
	[XmlElementAttribute("desc")]
	public Descriptor[] Description;
	
	[XmlElementAttribute("credits")]
	public Credit Credits;
	
	[XmlElementAttribute("date")]
	public string DateString;
	[XmlIgnore]
	public DateTime Date
	{
		get
		{
			if (DateString == null || DateString.Length == 0)
				return DateTime.MinValue;
			return DateTime.ParseExact(DateString, "yyyyMMdd", null);
		}
		set
		{
			DateString = value.ToString("yyyyMMdd");
		}
	}
	
	[XmlElementAttribute("category")]
	public Descriptor[] Category;
	
	[XmlElementAttribute("language")]
	public Descriptor Language;
	
	[XmlElementAttribute("orig-language")]
	public Descriptor OriginalLanguage;
	
	[XmlElementAttribute("length")]
	public Length LengthField;
	[XmlIgnore]
	public DateTime Length
	{
		get
		{
			if (LengthField == null)
				return DateTime.MinValue;
			if (LengthField.Units == LengthType.Hours)
				return new DateTime(0, 0, 0, LengthField.Value, 0, 0);
			else if (LengthField.Units == LengthType.Minutes)
				return new DateTime(0, 0, 0, 0, LengthField.Value, 0);
			else // assume LengthType.Seconds
				return new DateTime(0, 0, 0, 0, 0, LengthField.Value);
		}
		set
		{
			if (value.Hour != 0)
			{
				LengthField.Units = LengthType.Hours;
				LengthField.Value = value.Hour;
			}
			else if (value.Minute != 0)
			{
				LengthField.Units = LengthType.Minutes;
				LengthField.Value = value.Minute;
			}
			else // assume LengthType.Seconds
			{
				LengthField.Units = LengthType.Seconds;
				LengthField.Value = value.Second;
			}
		}
	}
	
	[XmlElementAttribute("icon")]
	public Icon[] Icon;
	
	[XmlElementAttribute("url")]
	public string[] URLs;
	
	[XmlElementAttribute("country")]
	public Descriptor[] Country;
	
	[XmlElementAttribute("episode-num")]
	public Episode Episode;
	
	[XmlElementAttribute("video")]
	public Video Video;
	
	[XmlElementAttribute("audio")]
	public Audio Audio;
	
	[XmlElementAttribute("previously-shown")]
	public Showing PreviousShowing;
	
	[XmlElementAttribute("premiere")]
	public Descriptor Premiere;
	
	[XmlElementAttribute("last-chance")]
	public Descriptor LastChance;
	
	[XmlElementAttribute("subtitles")]
	public Subtitle[] Subtitles;
	
	[XmlElementAttribute("rating")]
	public Rating[] Ratings;
	
	[XmlElementAttribute("star-rating")]
	public Rating StarRating;
	
	[XmlAttributeAttribute("start")]
	public string StartString;
	[XmlIgnore]
	public DateTime Start
	{
		get
		{
			if (StartString == null || StartString.Length == 0)
				return DateTime.MinValue;
			return DateTime.ParseExact(StartString, "yyyyMMddHHmmss zz00", null);
		}
		set
		{
			StartString = value.ToString("yyyyMMddHHmmss zz00");
		}
	}

	[XmlAttributeAttribute("stop")]	
	public string StopString;
	[XmlIgnore]
	public DateTime Stop
	{
		get
		{
			if (StopString == null || StopString.Length == 0)
				return DateTime.MinValue;
			return DateTime.ParseExact(StopString, "yyyyMMddHHmmss zz00", null);
		}
		set
		{
			StopString = value.ToString("yyyyMMddHHmmss zz00");
		}
	}
	
	[XmlAttributeAttribute("pdc-start")]
	public string PDCStart;
	
	[XmlAttributeAttribute("vps-start")]
	public string VPSStart;
	
	[XmlAttributeAttribute("showview")]
	public string ShowView;
	
	[XmlAttributeAttribute("videoplus")]
	public string VideoPlus;
	
	[XmlAttributeAttribute("channel")]
	public string ChannelID;
	
	[XmlAttributeAttribute("clumpidx")]
	[System.ComponentModel.DefaultValueAttribute("0/1")]
	public string ClumpIndex = "0/1";

	public int CompareTo(object obj)
	{
		if (obj.GetType() != typeof(Program))
			throw new ArgumentException("object is not a Program");
		Program that = (Program)obj;

		return this.Start.CompareTo(that.Start);
	}

	public override string ToString()
	{
		string title = "Program";
		if (Title != null)
			foreach (Descriptor d in Title)
				if (d.Language == "en")
					title = d.Value;
		if (Subtitle != null)
			foreach (Descriptor d in Subtitle)
				if (d.Language == "en")
					title += ": " + d.Value;

		return title;
	}

}

public class Credit 
{	
	public Credit()
	{
		Directors = new string[0];
		Actors = new string[0];
		Writers = new string[0];
		Adapters = new string[0];
		Producers = new string[0];
		Presenters = new string[0];
		Commentators = new string[0];
		Guests = new string[0];
	}

	[XmlElementAttribute("director")]
	public string[] Directors;
	
	[XmlElementAttribute("actor")]
	public string[] Actors;
	
	[XmlElementAttribute("writer")]
	public string[] Writers;
	
	[XmlElementAttribute("adapter")]
	public string[] Adapters;
	
	[XmlElementAttribute("producer")]
	public string[] Producers;
	
	[XmlElementAttribute("presenter")]
	public string[] Presenters;
	
	[XmlElementAttribute("commentator")]
	public string[] Commentators;
	
	[XmlElementAttribute("guest")]
	public string[] Guests;
}

public class Descriptor 
{	
	[XmlAttributeAttribute("lang")]
	public string Language;
	
	[XmlTextAttribute()]
	public string Value;
}

public class Length 
{
	public Length()
	{
		Value = 0;
	}

	[XmlAttributeAttribute("units")]
	public LengthType Units;
	
	[XmlTextAttribute()]
	public int Value;
}

public enum LengthType 
{ 
	[XmlEnum("seconds")]
	Seconds,

	[XmlEnum("minutes")]
	Minutes,

	[XmlEnum("hours")]
	Hours,
}

public class Episode 
{	
	[XmlAttributeAttribute("system")]
	[System.ComponentModel.DefaultValueAttribute("onscreen")]
	public string System = "onscreen";
	
	[XmlTextAttribute()]
	public string Value;
}

public class Video 
{	
	[XmlElementAttribute("present")]
	public string Present;

	[XmlElementAttribute("colour")]
	public string Colour;

	[XmlElementAttribute("aspect")]
	public string Aspect;
}

public class Audio 
{	
	[XmlElementAttribute("present")]
	public string Present;

	[XmlElementAttribute("stereo")]
	public string Stereo;
}

public class Showing 
{	
	[XmlAttributeAttribute("start")]
	public string StartString;
	[XmlIgnore]
	public DateTime Start
	{
		get
		{
			if (StartString == null || StartString.Length == 0)
				return DateTime.MinValue;
			return DateTime.ParseExact(StartString, "yyyyMMddHHmmss zz00", null);
		}
		set
		{
			StartString = value.ToString("yyyyMMddHHmmss zz00");
		}
	}
	
	[XmlAttributeAttribute("channel")]
	public string ChannelID;
}

public class Subtitle 
{	
	[XmlElementAttribute("language")]
	public Descriptor Language;
	
	[XmlAttributeAttribute("type")]
	public SubtitleType Type;
	
	/// <remarks/>
	[XmlIgnoreAttribute()]
	public bool typeSpecified;
}

public enum SubtitleType 
{	
	[XmlEnum("teletext")]
	TeleText,

	[XmlEnum("onscreen")]
	OnScreen,
}

public class Rating 
{	
	public Rating()
	{
		Icons = new Icon[0];
	}

	[XmlElementAttribute("value")]
	public string Value;
	
	[XmlElementAttribute("icon")]
	public Icon[] Icons;
	
	[XmlAttributeAttribute("system")]
	public string System;
}

